package com.ds.robot.assistant.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ds.robot.assistant.common.NumberUtil;
import com.ds.robot.assistant.dao.TargetOkrDao;
import com.ds.robot.assistant.entity.TargetAchievementEntity;
import com.ds.robot.assistant.entity.TargetOkrEntity;
import com.ds.robot.assistant.enums.ChangeDirection;
import com.ds.robot.assistant.enums.PrincipalType;
import com.ds.robot.assistant.enums.ValueType;
import com.ds.robot.assistant.service.TargetAchievementService;
import com.ds.robot.assistant.service.TargetOkrService;
import com.ds.robot.assistant.util.DateUtil;
import com.ds.robot.assistant.vo.OkrItemArchVO;
import com.ds.robot.assistant.vo.OkrItemVO;
import com.ds.robot.assistant.vo.OkrVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;


@Service("targetOkrService")
@Slf4j
public class TargetOkrServiceImpl extends ServiceImpl<TargetOkrDao, TargetOkrEntity> implements TargetOkrService {

    @Autowired
    private TargetAchievementService achievementService;

    // 排序
    private final List<PrincipalType> sortedKeys = Arrays.asList(PrincipalType.Z, PrincipalType.J, PrincipalType.D, PrincipalType.A);

    @Override
    public List<OkrVO> queryOrkList(String quarter) {
        // 查询所有启用的OKR
        List<TargetOkrEntity> okrEntityList = this.lambdaQuery().eq(TargetOkrEntity::getQuarter, quarter.trim())
                .eq(TargetOkrEntity::getStatus, 1)
                .orderByAsc(TargetOkrEntity::getTargetOrder)
                .list();

        // Map<Integer, List<TargetOkrEntity>> map = okrEntityList.stream().filter(entity -> entity.getTargetLevel() == 2)
        //         .sorted(Comparator.comparingInt(TargetOkrEntity::getTargetOrder))
        //         .collect(Collectors.groupingBy(TargetOkrEntity::getParentId,
        //                 Collectors.collectingAndThen(Collectors.toList(), list -> list.stream().sorted(Comparator.comparingInt(TargetOkrEntity::getTargetOrder)).collect(Collectors.toList()))));
        // System.out.println("map = " + map);

        // 二级OKR
        List<Integer> smallIdList = okrEntityList.stream().filter(okrEntity -> okrEntity.getTargetLevel() == 2 && okrEntity.getStatus() == 1)
                .map(TargetOkrEntity::getId).collect(Collectors.toList());
        log.info("idList = {}", smallIdList);

        // 查询目标达成情况
        // Date date;
        // try {
        //     date = new SimpleDateFormat("yyyy-MM-dd").parse("2024-10-26");
        // } catch (ParseException e) {
        //     throw new RuntimeException(e);
        // }
        List<TargetAchievementEntity> achievementList = achievementService.lambdaQuery()
                .in(TargetAchievementEntity::getTargetTypeId, smallIdList)
                .eq(TargetAchievementEntity::getAchievementDate, DateUtil.getDayBefore(2))
                // .eq(TargetAchievementEntity::getAchievementDate, date)//临时测试用
                .list();
        // 如果没有查询到达成数据，返回空
        if (CollectionUtils.isEmpty(achievementList)) {
            return Collections.emptyList();
        }
        Map<Integer, LinkedHashMap<PrincipalType, List<TargetAchievementEntity>>> achievementMapMap = achievementList.stream()
                .collect(
                        Collectors.groupingBy(TargetAchievementEntity::getTargetTypeId,
                                Collectors.collectingAndThen(
                                        Collectors.groupingBy(TargetAchievementEntity::getPrincipalType,
                                                LinkedHashMap::new,//HashMap::new
                                                Collectors.toList()
                                        ),
                                        // () -> new TreeMap<>(Comparator.comparingInt(p -> p.getOrder())),
                                        map -> {
                                            LinkedHashMap<PrincipalType, List<TargetAchievementEntity>> sortedMap = new LinkedHashMap<>();
                                            // 按照 Z,J,A/D 顺序遍历
                                            for (PrincipalType key : sortedKeys) {
                                                if (map.containsKey(key)) {
                                                    sortedMap.put(key, map.get(key));
                                                }
                                            }
                                            return sortedMap;
                                        }
                                )
                        )
                );
        // achievementMapMap = achievementList.stream().collect(
        //         Collectors.groupingBy(TargetAchievementEntity::getTargetTypeId,
        //                 Collectors.groupingBy(TargetAchievementEntity::getPrincipalType,
        //                         Collectors.collectingAndThen(
        //                                 Collectors.toList(),
        //                                 list -> list.stream().sorted(Comparator.comparingInt(o -> o.getPrincipalType().ordinal())).collect(Collectors.toList())
        //                         )
        //                 )
        //         )
        // );
        List<OkrVO> bigOkrList = okrEntityList.stream().filter(entity -> entity.getTargetLevel().equals(1))
                .map(entity -> {
                    OkrVO okrVO = new OkrVO();
                    okrVO.setId(entity.getId());
                    okrVO.setTargetName(entity.getTargetName());
                    okrVO.setTargetOrder(entity.getTargetOrder());
                    return okrVO;
                })
                .sorted(Comparator.comparingInt(OkrVO::getTargetOrder))
                .collect(Collectors.toList());

        if (!CollectionUtils.isEmpty(bigOkrList)) {
            // 遍历一级OKR
            for (OkrVO vo : bigOkrList) {
                // 遍历二级OKR
                List<OkrItemVO> itemVOList = okrEntityList.stream().filter(entity -> vo.getId().equals(entity.getParentId()))
                        .map(entity -> {
                            OkrItemVO itemVO = new OkrItemVO();
                            itemVO.setTargetName(entity.getTargetName());
                            itemVO.setTargetValue(entity.getTargetValue());
                            itemVO.setTargetOrder(entity.getTargetOrder());
                            itemVO.setValueType(entity.getValueType());
                            itemVO.setValueUnit(entity.getValueUnit());
                            LinkedHashMap<PrincipalType, List<TargetAchievementEntity>> linkedHashMap = achievementMapMap.get(entity.getId());

                            List<OkrItemArchVO> itemArchList = linkedHashMap.entrySet().stream().map(arch -> {
                                OkrItemArchVO okrItemArchVO = new OkrItemArchVO();
                                okrItemArchVO.setPrincipalType(arch.getKey());
                                // 只有一个
                                okrItemArchVO.setValue(arch.getValue().get(0).getValue());
                                okrItemArchVO.setChangeDirection(arch.getValue().get(0).getChangeDirection());
                                okrItemArchVO.setChangeValue(arch.getValue().get(0).getChangeValue());
                                return okrItemArchVO;
                            }).collect(Collectors.toList());

                            itemVO.setItemArchList(itemArchList);
                            return itemVO;
                        })
                        .sorted(Comparator.comparingInt(OkrItemVO::getTargetOrder))
                        .collect(Collectors.toList());

                if (!CollectionUtils.isEmpty(itemVOList)) {
                    vo.setItemList(itemVOList);
                }
            }
        }
        return bigOkrList;
    }

    @Override
    public String getOkrReportMessage(String quarter) {
        List<OkrVO> okrVOList = queryOrkList(quarter);
        if (CollectionUtils.isEmpty(okrVOList)) {
            log.info("没有OKR数据");
            return null;
        }
        StringBuilder message = new StringBuilder("# [部门核心OKR达成统计报告]\n");

        for (int i = 0; i < okrVOList.size(); i++) {
            OkrVO okrVO = okrVOList.get(i);
            message.append("## ").append(NumberUtil.numberToChinese(i + 1)).append("、").append(okrVO.getTargetName()).append("\n");

            for (int j = 0; j < okrVO.getItemList().size(); j++) {
                OkrItemVO itemVO = okrVO.getItemList().get(j);
                message.append("### ").append(j + 1).append(". ").append(itemVO.getTargetName()).append("\t目标值：")
                        .append(getShowValue(itemVO.getValueType(), itemVO.getTargetValue(), itemVO.getValueUnit())).append("\n");

                List<OkrItemArchVO> itemArchList = itemVO.getItemArchList();
                for (OkrItemArchVO archVO : itemArchList) {
                    message.append(" > ").append(archVO.getPrincipalType().getDesc());
                    if (PrincipalType.D.equals(archVO.getPrincipalType())) {
                        //加盟商的指标不需要追加达成值
                        message.append("：");
                    } else {
                        message.append("达成值：");
                    }
                    message.append(getShowValue(itemVO.getValueType(), archVO.getValue(), itemVO.getValueUnit()));

                    if (archVO.getChangeDirection() != null) {
                        message.append("\t环比").append(getDesc(archVO.getChangeDirection())).append("：")
                                .append(getPercent(archVO.getChangeValue()))
                                .append("\n");
                    } else {
                        message.append("\n");
                    }
                }
                message.append("\n");
            }
        }
        message.append("\n\n");
        message.append("\n <@wjn> <@w> <@liuchen_tqav> <@jianghaipeng_6g1v>  <@lanhuimin_mkfr> " +
                "<@limengqian_ft2b> <@Miyanchun> <@qinxuetao_77fj> <@zhangzhixian_brzp> <@dengzhongjian_sgp6> <@所有人> \n请悉知~");
        return message.toString();
    }

    public static String getDesc(ChangeDirection direction) {
        switch (direction) {
            case U:
                return "<font color=\"warning\">**上升**</font>";
            case D:
                return "<font color=\"info\">**下降**</font>";
            case S:
            default:
                return "持平";
        }
    }

    @Override
    public int queryOkrItemCount(String quarter) {
        Long count = this.lambdaQuery().eq(TargetOkrEntity::getQuarter, quarter)
                .eq(TargetOkrEntity::getTargetLevel, 2)
                .eq(TargetOkrEntity::getStatus, 1)
                .count();
        return Math.toIntExact(count);
    }

    private String getPercent(BigDecimal v) {
        BigDecimal percentage = v.multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP);
        return percentage + "%";
    }

    private String getShowValue(ValueType valueType, BigDecimal value, String valueUnit) {
        String msg;
        switch (valueType) {
            case P:
                msg = value + "%";
                break;
            case I:
                msg = value == null ? "0" : String.valueOf(value.intValue());
                break;
            case N:
            default:
                msg = value + "";
                break;
        }
        if (StringUtils.hasText(valueUnit)) {
            msg += valueUnit;
        }
        return msg;
    }
}
